博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何使用Create React App DevOps自动化工作中所有无聊的部分
阅读量:2520 次
发布时间:2019-05-11

本文共 21949 字,大约阅读时间需要 73 分钟。

by James Y Rauhut

詹姆士·鲁豪(James Y Rauhut)

如何使用Create React App DevOps自动化工作中所有无聊的部分 (How I automate all of the boring parts of my job with Create React App DevOps)

When you have responsibilities as one of the only designers — and possibly developer s— on your team, automation becomes your best friend.

当您作为团队中仅有的设计师(甚至是开发人员)之一负责时,自动化将成为您最好的朋友。

At work, I have both responsibilities as a designer and sometimes as a lone developer. This means that there is not much time to configure the dev environment I am working on. Time is also wasted when I have to manually update the apps to their online environment.

在工作中,我既担负设计师的职责,有时也承担着独自开发的职责。 这意味着没有太多时间来配置我正在开发的开发环境。 当我不得不手动将应用程序更新到其在线环境时,也浪费了时间。

Thankfully, there are free tools that help us prototype and release in no time: Create React App, Bluemix, GitHub, and Travis CI. I’m going to share with you how I use all of these to automate all of the boring parts of my job with .

值得庆幸的是,有免费的工具可以帮助我们立即进行原型设计和发布:创建React App,Bluemix,GitHub和Travis CI。 我将与您分享如何使用所有这些通过自动执行工作中所有无聊的部分。

Update March 3rd, 2017: Thanks to a heads up from a commenter, I was warned not to use Babel-Node in production (on Bluemix). now reflects that with v1.1.0!

2017年3月3日更新:感谢评论者的注意,警告我不要在生产中使用Babel-Node(在Bluemix上)。 现在,使用v1.1.0可以 !

There are three ways you can adapt this process yourself:

您可以通过三种方式自己调整此过程:

  • Follow along with this post as we write the project together

    在我们一起编写项目时,跟随这篇文章
  • Inspect the comparison between the initial Create React App use and the final commit:

    检查最初的Create React App使用和最终提交 :

  • Fork the repo and follow the instructions below:

    分叉仓库,并按照以下说明进行操作:

Check out the app live at: https

通过实时查看该应用程序:https

If you want to know the guts of the project, then continue reading to make it with me! There will be six sections:

如果您想了解该项目的精髓,请继续阅读以与我合作! 将分为六个部分:

  1. Use Create React App to Get the UI Up

    使用Create React App来建立UI
  2. Setup Your Server with Node, Express, and Babel

    使用Node,Express和Babel设置服务器
  3. Run the App on the Web with Bluemix

    使用Bluemix在Web上运行应用程序
  4. Automagically Deploy from Github with Travis CI

    使用Travis CI从Github自动部署
  5. Fetch API Data While Keeping Keys Secure

    在保持密钥安全的同时获取API数据
  6. Create a Staging App for Experimentation

    创建暂存应用进行实验

()

When I first started using React for front-end projects, I wasted a lot of time. A lot of that time was configuring Webpack and various plug-ins. Thankfully, Create React App was created to keep your projects configured properly. There is an option to “eject” your Create React App projects, but I avoid ejecting. That is so that I can continue receiving Facebook’s updates to the project.

当我第一次开始将React用于前端项目时,我浪费了很多时间。 大部分时间是配置Webpack和各种插件。 幸运的是,创建React应用程序是为了保持您的项目正确配置。 有一个选项可以“弹出”您的Create React App项目,但是我避免弹出。 这样一来,我就可以继续接收Facebook对项目的更新。

  1. to manage the packages we use and server.

    来管理我们使用的软件包和服务器。

  2. (optional) to speed up the installation of packages. If you choose not to, just keep in mind that terminal commands like yarn run --- are usually npm run ---.

    (可选)以加快软件包的安装。 如果您选择不这样做,则请记住,诸如yarn run ---类的终端命令通常是npm run ---

  3. It is time to open up your terminal. Install Create React App globally: yarn global add create-react-app

    现在是时候打开您的终端了。 全局安装Create React App: yarn global add create-react-app

  4. Now let Create React App make your project or you and navigate into it: create-react-app <app-name>; and cd <app-name>

    现在,让Create React App创建您的项目或进入您的项目: create-react-app <app-na me> ; and cd < ; and cd <应用程序名称>

Side Note: Anytime you see “<app-name>” in this write-up, you can replace it with a unique name for your project like “super-cool-app”.

旁注 :只要在本文中看到“ <app-name>”,就可以用项目的唯一名称替换它,例如“ super-cool-app”。

?????? (?????)

You can now work on all of the client-side (user interface) code! Run yarn start and Create React App will open a tab in your browser to show you the UI. Anytime you edit the client-side code in the <app-name>;/src/, the browser will refresh with the changes!?????

现在,您可以处理所有客户端(用户界面)代码! 运行yarn start ,Create React App将在浏览器中打开一个标签,向您显示UI。 每当您在<app-name> ; / src /中编辑客户端代码时,浏览器都会刷新所做的更改!

()

Now let’s get a server running so that you can host the app online. Controlling your own Node server will also be important later to fetch data with an API from services like Github.

现在,让服务器运行,以便您可以在线托管应用程序。 稍后,控制自己的Node服务器对于从Github之类的服务中使用API​​获取数据也很重要。

  1. Let’s add all of the packages for a Node server. The Babel related packages will allow you to use the latest Javascript functionality: yarn add babel-cli babel-preset-es2015 babel-preset-stage-2 compression express

    让我们为节点服务器添加所有软件包。 与Babel相关的软件包将允许您使用最新的Javascript功能: yarn add babel-cli babel-preset-es2015 babel-preset-stage-2 compression express

  2. Now make an index.js file in the root of the project folder to represent our Node server:

    现在,在项目文件夹的根目录中创建一个index.js文件,以表示我们的节点服务器:

import compression from 'compression';import express from 'express'; const app = express();const port = process.env.PORT || 8080;app.use(compression()); app.use(express.static('./build')); app.listen(port, (err) => { if (err) {   console.log(err);   return; }
console.log(`Server is live at http://localhost:${port}`);});

3. You can now see all of the dependencies we installed in package.json. Let’s add a script called “bluemix” to run the server and section called “babel” to configure Babel:

3.现在,您可以看到我们在package.json安装的所有依赖项。 让我们添加一个名为“ bluemix”的脚本来运行服务器,并添加一个名为“ babel”的部分来配置Babel:

"scripts": {  "bluemix": "babel-node index.js",  "start": "react-scripts start",  "build": "react-scripts build",  "test": "react-scripts test --env=jsdom",  "eject": "react-scripts eject",},"babel": {  "presets": [    "es2015",    "stage-2"  ]}

4. yarn build && yarn bluemix will build the app and run the server. However, we want to add a dev mode to the server similar to our client-side code. This way we see changes from just saving index.js when we are coding. Let’s add some dependencies that will let us do this: yarn add babel-watch concurrently --dev

4. yarn build && yarn bluemix将构建应用程序并运行服务器。 但是,我们希望向服务器添加类似于客户端代码的开发模式。 通过这种方式,我们看到了在编码时仅保存index.js变化。 让我们添加一些依赖关系,让我们做到这一点: yarn add babel-watch concurrently --dev

5. Now update the “start” script in package.json so that we run Create React App’s dev mode and our server. We will also add a “proxy” line. This line tells Create React App that a server can take requests that are not found in the client-side code:

5.现在更新package.json中的“ start”脚本,以便我们运行Create React App的dev模式和我们的服务器。 我们还将添加“代理”行。 此行告诉Create React App服务器可以接受客户端代码中未找到的请求:

"proxy": "http://localhost:8081","scripts": {  "bluemix": "babel-node index.js",  "start": "concurrently \"PORT=8080 react-scripts start\" \"PORT=8081 babel-watch index.js\"",  "build": "react-scripts build",  "test": "react-scripts test --env=jsdom",  "eject": "react-scripts eject",},

?????? (?????)

You can now work on the server-side code in index.js! Run yarn start and both the Create React App dev mode and our server will respond to changes saved!?????

您现在可以在index.js的服务器端代码上工作了! 运行yarn start和Create React App dev模式,我们的服务器将响应保存的更改!

()

Since I work at IBM, Bluemix is our go-to hosting platform. Not only do we host our final products on Bluemix, but we also host any prototypes to share with peers and user test. I also use Bluemix for personal projects like this one because it has a solid free tier.

自从我在IBM工作以来,Bluemix是我们的首选托管平台。 我们不仅将最终产品托管在Bluemix上,而且还托管任何原型以与同行和用户测试共享。 我还将Bluemix用于这样的个人项目,因为它具有可靠的免费层。

  1. Create a free account on .

    在上创建一个免费帐户。

  2. Install the . Since Bluemix is built on top of an open-source project called Cloud Foundry, you will see “cf” in a lot of our commands.

    安装 。 由于Bluemix是建立在一个名为Cloud Foundry的开源项目之上的,因此您会在许多命令中看到“ cf”。

  3. Similar to .gitignore files, we should make a file to prevent unnecessary files from being uploaded to Bluemix. Make .cfignore in the project’s root folder to do this:

    .gitignore文件类似,我们应该制作一个文件,以防止将不必要的文件上传到Bluemix。 在项目的根文件夹.cfignore为执行以下操作:

/node_modules .DS_Store npm-debug.log* yarn-debug.log* yarn-error.log*

4. Now we can tell Bluemix all of our app’s settings for the deploy with a manifest.yml file in the root of the project:

4.现在,我们可以在项目根目录中使用manifest.yml文件来告诉Bluemix我们所有应用程序的设置设置:

---applications:- name: 
buildpack: https://github.com/cloudfoundry/nodejs-buildpack command: npm run bluemix disk_quota: 256MB memory: 128MB

5. Finally, login into Bluemix from your terminal with cf login -a https://api.ng.bluemix.net, build your app with yarn build, and then push your app into the world with cf push.

5.最后,使用cf login -a https://api.ng.bluemix.net从您的终端登录Bluemix,使用yarn build构建您的应用程序,然后使用cf push将您的应用程序推向世界。

?????? (?????)

After about five minutes, your terminal should say the app is live at <app-name>.mybluemix.net! Now the world can see it. A common error is that your app name has already been taken on Bluemix. Simply choose a more unique name and it should work!?????

大约五分钟后,您的终端应显示该应用程序已在<app-name> .mybluemix.net上运行! 现在世界可以看到它。 一个常见的错误是您的应用程序名称已在Bluemix上获取。 只需选择一个更独特的名称,它就可以工作!

()

One of the most tedious parts of managing an app is deploying it every time you have changes ready. I would even get lazy and batch my deploys whenever I finally felt like doing it. Thanks to Travis CI (Continuous Integration), deploying can become as simple as .

每次准备好进行更改时,管理应用程序中最繁琐的工作之一就是对其进行部署。 每当我最终想做的时候,我什至会变得懒惰并批处理我的部署。 借助Travis CI(持续集成),部署可以像一样简单。

  1. First, you need to make a and set up the .

    首先,您需要注册一个并设置 。

  2. Next, create a new repo on and then follow the terminal instructions provided to push your project to Github:

    接下来,在上创建一个新的 ,然后按照提供的终端说明将项目推送到Github:

git initgit add .git commit -m 'Initial commit'git remote add origin https://github.com/
.gitgit push -u origin master

3. Now head over to to login with your Github credentials. Hit the “+” icon to activate your new repo. If you do not see the repo you just created, click “Sync account” and then it should show up.

3.现在转到 ,使用您的Github凭据登录。 点击“ +”图标激活您的新仓库。 如果没有看到您刚刚创建的存储库,请单击“同步帐户”,然后它将显示。

4. Then click on the project’s settings in Travis to choose the following options:

4.然后在Travis中单击项目的设置以选择以下选项:

Build only if .travis.yml is present = OnBuild pushes = OnLimit concurrent jobs = OffBuild pull requests = On (This will allow Github to still run any automated tests you add in the future for opened PRs.)Environment Variables: BLUEMIX_PASSWORD = <Your-bluemix-password>

仅当存在.travis.yml时才进行构建= OnBuild推送= OnLimit并发作业= OffBuild拉取请求= On(这将使Github仍可以运行您将来为打开的PR添加的任何自动化测试。)环境变量: BLUEMIX_PASSWORD = <Your-bluemix-passwo rd>

5. The biggest step here is adding the blueprint for Travis as a .travis.yml file in the project’s root:

5.这里最大的步骤是将Travis的蓝图作为.travis.yml文件添加到项目根目录中:

sudo: truelanguage: node_jsnode_js:- '5.7'cache:  yarn: true  directories:    - node_modulesenv:  global:  - CF_API=https://api.ng.bluemix.net/  - CF_USERNAME=
- CF_ORG=
- CF_SPACE=devbefore_deploy: - wget https://s3.amazonaws.com/go-cli/releases/v6.12.4/cf-cli_amd64.deb -qO temp.deb && sudo dpkg -i temp.deb - rm temp.deb - cf login -a ${CF_API} -u ${CF_USERNAME} -p ${BLUEMIX_PASSWORD} -o ${CF_ORG} -s ${CF_SPACE} - cf install-plugin autopilot -r CF-Community - yarn builddeploy: - edge: true provider: script script: if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then cf zero-downtime-push
-f ./manifest.yml; else echo "PR skip deploy"; fi skip_cleanup: true on: branch: master

Important: Notice that there two places where you insert your Bluemix email and one place where you insert the name of the app on Bluemix!

重要:请注意,有两个地方可以插入您的Bluemix电子邮件,一个地方可以在Bluemix上插入应用程序的名称!

There is a lot going on here. So I will try to summarize it: In the before_deploy section, Travis is building the app, logging into Bluemix as you, and then downloading a Cloud Foundry plugin called Autopilot. Then in the deploy section, Travis decides if the deploy is an open pull request or an actual commit to the Github master branch. If it is an actual commit, run Autopilot to deploy the app.

这里有很多事情。 因此,我将尝试总结一下:在before_deploy部分中,Travis正在构建应用程序,以您的身份登录到Bluemix,然后下载一个名为Autopilot的Cloud Foundry插件。 然后,在“部署”部分中,Travis决定部署是开放拉取请求还是对Github master分支的实际提交。 如果是实际提交,请运行Autopilot部署应用程序。

Autopilot practices Blue-Green Deployment. This means that the new version of your app will be given the name <my-app>-venerable on Bluemix. If the new version builds and runs successfully, the old version of the app is deleted and the new version renames itself to the original name. If the deploy fails, <my-app&gt;-venerable stays up so that you can debug the logs and the old version of the app keeps running so your users see zero downtime!

自动驾驶仪实行蓝绿色部署。 这意味着您的应用程序的新版本将被命名为<my-app>-ven在Bluemix上具有较高的声誉。 如果新版本生成并成功运行,则该应用的旧版本将被删除,新版本会将其自身重命名为原始名称。 如果部署ails, <my-app&g t; -venerable会保持运行状态,以便您可以调试日志,并且旧版本的应用程序将继续运行,从而使用户看到的停机时间为零!

?????? (?????)

Dope DevOps, Batman! Navigate to https://travis-ci.org/<github-username>/<app-name>/builds and you should see a Travis build about to happen. If you click into it, you can watch it start and follow it deploying for you!?????

Dope DevOps,蝙蝠侠! 导航至https://travis-ci.org/<github-username>/<app-nam e> / builds,您应该看到Travis构建即将发生。 如果单击它,您可以观看它的启动并为您部署它!

()

Most apps use data from different sources to put together their offerring. For an app to get external data, they use an API to fetch the data. For the API to make sure the right app is fetching data, the app is given a key to identify itself. We need to keep this key secret from our Github repo though!

大多数应用程序使用来自不同来源的数据来汇总其报价。 为了使应用程序获取外部数据,他们使用API​​来获取数据。 为了使API确保正确的应用程序正在获取数据,将为该应用程序提供一个用于标识自身的密钥。 不过,我们需要从我们的Github存储库中保守这个关键秘密!

  1. First, let’s ask the . Under “Select scopes”, we will check public_repo to get your repo information. Click “Generate token” and then you will get a key next to a green checkmark!

    首先,让我们向索要 。 在“选择范围”下,我们将检查public_repo以获取您的回购信息。 单击“生成令牌”,然后您将在绿色复选标记旁边看到一个密钥!

  2. It is time to add the key to our project locally as keys.json in the root of our project:

    现在是时候在项目根目录中将key作为keys.json本地添加到我们的项目中了:

{  "github": "
"}

However, we do not want your precious key to be uploaded to your Github repo. So, add this file to your .gitignore file:

但是,我们不希望将您的宝贵密钥上传到您的Github存储库中。 因此,将此文件添加到您的.gitignore文件中:

# misc.DS_Store.envnpm-debug.log*yarn-debug.log*yarn-error.log*keys.json

3. Now that we have your key, we can add a server request. Install Request to your project with yarn add request and then edit your server’s index.js:

3.现在我们有了您的密钥,我们可以添加服务器请求。 使用yarn add request将Request安装到项目中,然后编辑服务器的index.js

import compression from 'compression';import express from 'express';import fs from 'fs';import request from 'request';
const app = express();const port = process.env.PORT || 8080;app.use(compression());
let keys;if (fs.existsSync('./keys.json')) {  keys = require('./keys.json');} else {  keys = JSON.parse(process.env.VCAP_SERVICES)['user-provided'][0].credentials;}
app.get('/github', (req, res) => {  request({    url: `https://api.github.com/user/repos?affiliation=owner,collaborator&access_token=${keys.github}`,    headers: {      'user-agent': 'node.js',    },  }, (err, response, body) => {    if (!err && response.statusCode === 200) {      res.send(body);    }  });});
app.use(express.static('./build'));
app.listen(port, (err) => {  if (err) {    console.log(err);    return;  }  console.log(`Server is live at http://localhost:${port}`);});

You will first notice an if statement checking if we have the local keys.json file. The “else” in that statement will cover when the app is on Bluemix later. We then have an endpoint where pinging will return your profile’s repos!

您将首先注意到一条if语句,用于检查我们是否具有本地keys.json文件。 该语句中的“其他”将覆盖应用程序稍后在Bluemix上使用的时间。 然后,我们有了一个终结点,在该终结点上ping 将返回您的配置文件的存储库!

4. Open up src/App.js to fetch that data to your UI from your server. After these additions, yarn start should show all of your project’s repos listed :

4.打开src/App.js以将数据从服务器获取到UI中。 添加完这些之后, yarn start应该会列出您项目的所有存储库:

import React, { Component } from 'react';import logo from './logo.svg';import './App.css';
class App extends Component {
state = {    repos: [],  }
componentDidMount() {    fetch('/github')    .then(response => response.json())    .then((data) => {      const repos = data.map((repo) =>        

{repo.name}

);
this.setState({ repos })    });  }
render() {    return (      
logo

Welcome to React

To get started, edit src/App.js</code> and save to reload.

App Creator's Repos:

{this.state.repos}
); }}
export default App;

5. Now that we can use the Github API securely in dev mode, let’s make sure your Bluemix app can also get the API key. We are going to create a user-provided service on Bluemix in the terminal: cf cups keys -p keys.json. Then tell the manifest.json that the app should always bind itself to that service:

5.现在我们可以在开发人员模式下安全地使用Github API,让我们确保您的Bluemix应用程序也可以获取API密钥。 我们将在终端上的Bluemix上创建一个用户提供的服务: cf cups keys -p keys.json 。 然后告诉manifest.json应用程序应始终将自身绑定到该服务:

---applications:- name: 
buildpack: https://github.com/cloudfoundry/nodejs-buildpack command: npm run bluemix disk_quota: 256MB memory: 128MB services: - keys

Side Note: If you ever need to update the keys on Bluemix, you can run cf uups keys -p keys.json!

旁注:如果需要更新Bluemix上的键,则可以运行cf uups keys -p keys.json

?????? (?????)

After Travis updates your Bluemix app, you should see the UI fetching all of your repos live on the web! We did go through a lot of trouble keeping the keys off of github.com. This is because other devs can abuse your API keys if they get a lot of them.?????

Travis更新您的Bluemix应用程序之后,您应该会看到UI实时在网络上获取所有存储库! 在将密钥保留在github.com上的过程中,我们确实遇到了很多麻烦。 这是因为其他开发人员如果得到很多,则会滥用您的API密钥。

()

Now that our production version of the app has DevOps set up, let’s build a staging app. This will help us share works-in-progress for user testing and peer review!

现在我们的应用程序生产版本已设置DevOps,让我们构建一个临时应用程序。 这将帮助我们共享正在进行的工作,以进行用户测试和同行评审!

  1. We need to make a manifest file for Bluemix that specifies our new staging app now. In the root of your project, make a manifest-staging.yml file:

    我们需要为Bluemix创建一个清单文件,该清单文件现在指定我们的新暂存应用程序。 在项目的根目录中,创建一个manifest-staging.yml文件:

---applications:- name: 
-staging buildpack: https://github.com/cloudfoundry/nodejs-buildpack command: npm run bluemix disk_quota: 256MB memory: 128MB services: - keys

2. Go ahead and deploy this staging app directly to Bluemix with the new manifest file: cf push -f manifest-staging.yml

2.继续,使用新的清单文件将这个登台应用程序直接部署到Bluemix: cf push -f manifest-staging.yml

3. Then we are going to edit the deploy scripts in .travis.yml. We need to change the original deploy script for when we commit to master to update the new staging app. We also need to add a new deploy script for the original production app:

3.然后,我们将在.travis.yml编辑部署脚本。 当我们承诺掌握更新新的登台应用程序时,我们需要更改原始的部署脚本。 我们还需要为原始生产应用添加新的部署脚本:

deploy:  - edge: true    provider: script    script: if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then cf zero-downtime-push 
-staging -f ./manifest-staging.yml; else echo "PR skip deploy"; fi skip_cleanup: true on: branch: master - edge: true provider: script script: if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then cf zero-downtime-push
-f ./manifest.yml; else echo "PR skip deploy"; fi skip_cleanup: true on: tags: true

So now that we update the staging app by committing to the Github master branch, how do we update the production app? You will use as if your app is a real offerring. ?

因此,现在我们通过提交到Github master分支来更新登台应用程序,我们如何更新生产应用程序? 您将使用 ,就好像您的应用程序是真正一样。 ?

4. Go ahead and push your latest changes to Github! Then navigate to “Releases” on the Github repo and create a new release.

4.继续并将最新更改推送到Github! 然后导航到Github存储库上的“发布”并创建一个新版本。

?????? (?????)

Based on the last step, you should see two builds in queue on Travis CI. One will be the staging app updating because of the latest commit. The other will be your production app updating because of the new release!?????

基于最后一步,您应该在Travis CI上看到两个构建队列。 其中之一将是登台应用程序更新,因为最新的提交。 另一个将是由于新版本而更新您的生产应用程序!

DevOps的最终,最重要的价值 (The Final, Most Important Value of DevOps)

I want to end this write-up by stressing the most important part of DevOps: automated testing. Whenever Travis runs, including in opened pull requests, it will check that the command yarn test passes before taking action. Create React App already has yarn test configured with . However, you can add accessibility, linting, and any other testing framework you are familiar with!

我想通过强调DevOps的最重要部分: 自动化测试来结束本文。 每当Travis运行时,包括在打开的拉取请求中,它将在执行操作之前检查命令yarn test通过。 Create React App已经使用配置了yarn test 。 但是,您可以添加可访问性,棉绒和您熟悉的任何其他测试框架!

To recap what we have done: First, we quickly got our React project configured thanks to Create React App. Then we built a simple server. We pushed the app into the world. Next, we got Travis deploying the app (with zero downtime) for any of our changes. Then we used the Github API while keeping our key away from public eyes. Lastly, we also set up a staging app so that we could test pre-release.

回顾一下我们所做的事情:首先,借助Create React App,我们快速配置了React项目。 然后,我们构建了一个简单的服务器。 我们将应用程序推向了世界。 接下来,我们让Travis为我们的任何更改部署了应用程序(停机时间为零)。 然后,我们使用Github API,同时使我们的密钥远离公众。 最后,我们还设置了一个临时应用程序,以便我们可以测试预发布版本。

I hope this project has helped make your workflow easier as you make epic web apps! A big ? goes to the contributors of B C E N and all other packages used. Also, all the ❤️️ goes to Bluemix, Github, and Travis CI for their free tiers.

我希望这个项目可以帮助您在制作史诗般的Web应用程序时简化工作流程! 一个大的 ? B C N 和所有其他使用的软件包的贡献者。 而且,所有❤️️都可以免费获得Bluemix,Github和Travis CI。

Please share in the comments or if this helped you! I also would love to hear of different workflows!

请分享评论或通过如果这对您有帮助! 我也很想听听不同的工作流程!

You can also contact me by leaving a comment, , or tweeting to . I work in ATX for IBM Design, and always love conversations with the web design community.

您还可以通过发表评论, 或发推文到来与我联系。 我在ATX for IBM Design工作,并且一直喜欢与Web设计社区的对话。

You may also like…

您可能还喜欢…

查看 (Check out )

翻译自:

转载地址:http://cvgwd.baihongyu.com/

你可能感兴趣的文章
JAVA编码(52)—— API接口安全性设计
查看>>
c:"WINDOWS"Microsoft.NET"Framework"v2.0.50727"Temp
查看>>
android EditText自动弹出和自动关闭软键盘
查看>>
吉特日化MES-工业生产盲区
查看>>
Codeforces 517 #B
查看>>
实验四
查看>>
Scramble String
查看>>
php之接口概念
查看>>
01、计算机原理结构,及冯诺依曼体系结构
查看>>
Python 列表基本操作
查看>>
Linux TC基于CBQ队列的流量管理范例
查看>>
Python hashlib and hmac
查看>>
Fitnesse Page 简单使用
查看>>
C#.net 创建XML
查看>>
1057 数零壹
查看>>
隐马尔科夫模型(上)
查看>>
asp.net mvc FluentValidation 的使用
查看>>
java JvM
查看>>
HDU 1009 Just a Hook
查看>>
python基础之数据类型
查看>>